package com.ruoyi.system.controller;

import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.system.domain.SysExpert;
import com.ruoyi.system.domain.SysProjectExpertExtract;
import com.ruoyi.system.service.ISysExpertService;
import com.ruoyi.system.service.ISysProjectExpertExtractService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.SysProjectExpertConfig;
import com.ruoyi.system.domain.SysProjectExpertExtract;
import com.ruoyi.system.service.ISysProjectExpertConfigService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 专家抽取设置Controller
 *
 * @author ruoyi
 * @date 2024-08-08
 */
@RestController
@RequestMapping("/system/projectexpertconfig")
public class SysProjectExpertConfigController extends BaseController {
    @Autowired
    private ISysProjectExpertConfigService sysProjectExpertConfigService;

    @Autowired
    private ISysProjectExpertExtractService sysProjectExpertExtractService;

    @Autowired
    private ISysExpertService sysExpertService;

    /**
     * 查询专家抽取设置列表
     */
    @PreAuthorize("@ss.hasPermi('system:projectexpertconfig:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysProjectExpertConfig sysProjectExpertConfig) {
        startPage();
        List<SysProjectExpertConfig> list = sysProjectExpertConfigService.selectSysProjectExpertConfigList(sysProjectExpertConfig);
        return getDataTable(list);
    }

    /**
     * 导出专家抽取设置列表
     */
    @PreAuthorize("@ss.hasPermi('system:projectexpertconfig:export')")
    @Log(title = "专家抽取设置", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysProjectExpertConfig sysProjectExpertConfig) {
        List<SysProjectExpertConfig> list = sysProjectExpertConfigService.selectSysProjectExpertConfigList(sysProjectExpertConfig);
        ExcelUtil<SysProjectExpertConfig> util = new ExcelUtil<SysProjectExpertConfig>(SysProjectExpertConfig.class);
        util.exportExcel(response, list, "专家抽取设置数据");
    }

    /**
     * 获取专家抽取设置详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:projectexpertconfig:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Integer id) {
        return success(sysProjectExpertConfigService.selectSysProjectExpertConfigById(id));
    }

    /**
     * 新增专家抽取设置
     */
    @PreAuthorize("@ss.hasPermi('system:projectexpertconfig:add')")
    @Log(title = "专家抽取设置", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysProjectExpertConfig sysProjectExpertConfig) {
        return toAjax(sysProjectExpertConfigService.insertSysProjectExpertConfig(sysProjectExpertConfig));
    }

    /**
     * 修改专家抽取设置
     */
    @PreAuthorize("@ss.hasPermi('system:projectexpertconfig:edit')")
    @Log(title = "专家抽取设置", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysProjectExpertConfig sysProjectExpertConfig) {
        return toAjax(sysProjectExpertConfigService.updateSysProjectExpertConfig(sysProjectExpertConfig));
    }

    /**
     * 删除专家抽取设置
     */
    @PreAuthorize("@ss.hasPermi('system:projectexpertconfig:remove')")
    @Log(title = "专家抽取设置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Integer[] ids) {
        return toAjax(sysProjectExpertConfigService.deleteSysProjectExpertConfigByIds(ids));
    }

    @PreAuthorize("@ss.hasPermi('system:projectexpertconfig:extract')")
    @Log(title = "专家抽取", businessType = BusinessType.OTHER)
    @PostMapping("/extract")
    public AjaxResult extract(@RequestBody SysProjectExpertConfig sysProjectExpertConfig) {
        SysProjectExpertConfig configData = sysProjectExpertConfigService.selectSysProjectExpertConfigById(sysProjectExpertConfig.getId());
        if (configData == null) {
            return AjaxResult.error(HttpStatus.WARN, "专家抽取配置不存在");
        }

        // 查询抽取次数
        SysProjectExpertExtract sysProjectExpertExtract = new SysProjectExpertExtract();
        //sysProjectExpertExtract.setExpertConfigId(configData.getId().longValue());
        List<SysProjectExpertExtract> projectExpertExtractList = sysProjectExpertExtractService.selectSysProjectExpertExtractList(sysProjectExpertExtract);
        int extractedNum = projectExpertExtractList.size();   // 已抽取次数
        if (extractedNum == configData.getExtractNum()) {
            return AjaxResult.error(HttpStatus.WARN, "专家抽取已完毕");
        }

        int extractedExpertNum = 0;                                 // 已经抽取专家人次
        List<String> extractedList = new ArrayList<String>();       // 已经抽取的专家
        List<String> noExpertIds = new ArrayList<String>();         // 回避专家
        if (configData.getNoExpertIds() != null) {
            noExpertIds = Arrays.asList(configData.getNoExpertIds().split(","));
        }

        // 遍历抽取记录
        for (SysProjectExpertExtract projectExpertExtract : projectExpertExtractList) {
            String[] projectExpertArray = projectExpertExtract.getExpertId().split(",");
            extractedExpertNum = extractedExpertNum + projectExpertArray.length;    // 计算抽取专家人次
            for (String expertId : projectExpertArray) {
                extractedList.add(expertId);        // 追加已经抽取的专家
            }
        }

        // 计算最大抽取人数
        int expertNum = 0;      // 计算最大抽取专家数量
        int residueNum = configData.getExtractNum().intValue() - extractedNum;
        if (residueNum == 1) {
            // 计算生产抽取人数
            expertNum = configData.getExpertNum().intValue() - extractedExpertNum;
        } else {
            // 第一步：计算最大抽取人数
            int maxExtractNum = configData.getExpertNum().intValue() - extractedExpertNum - (residueNum - 1);
            Random random = new Random();
            // 第二步：设置抽取专家人数
            expertNum = random.nextInt(maxExtractNum) + 1; // 生成1到maxExtractNum的随机数
        }

        // 组装专家查询条件
        SysExpert expertsParams = new SysExpert();
        Map<String, Object> paramsMap = new HashMap<>();
        if (configData.getExpertGroupId() != null) {
            List<String> expertIdList = new ArrayList<String>();         // 候选专家
            List<String> expertGroupIdList = Arrays.asList(configData.getExpertGroupId().split(","));
            for (String groupId : expertGroupIdList) {
                if (!noExpertIds.contains(groupId) && !extractedList.contains(groupId)) {
                    expertIdList.add(groupId);
                }
            }
            paramsMap.put("ids", expertIdList);
        }
        if (noExpertIds.size() > 0) {
            paramsMap.put("notInIds", noExpertIds);
        }
        if (configData.getExpertAreaId() != null) {
            expertsParams.setAreaId(configData.getExpertAreaId());
        }
        if (configData.getExpertNum() > 0) {
            paramsMap.put("limit", configData.getExpertNum() * 3);
        }
        expertsParams.setParams(paramsMap);
        List<SysExpert> extractExperts = sysExpertService.selectSysExpertList(expertsParams);
        // 随机打乱List中的元素
        Collections.shuffle(extractExperts);
        // 从打乱后的List中取出前sampleSize个元素作为样本
        List<SysExpert> extractResult = extractExperts.subList(0, expertNum);

        List<String> extractExpertId = new ArrayList<String>();         // 抽取的专家ID
        List<String> extractExpertName = new ArrayList<String>();       // 抽取的专家名称
        for (SysExpert expert : extractResult) {
            extractExpertId.add(expert.getId().toString());
            extractExpertName.add(expert.getExpertName());
        }
        // 写抽取记录
        SysProjectExpertExtract projectExpertExtractData = new SysProjectExpertExtract();
        //projectExpertExtractData.setExpertConfigId(Long.valueOf(configData.getId()));
        projectExpertExtractData.setProjectId(configData.getProjectId());
        projectExpertExtractData.setProjectName(configData.getProjectName());
        projectExpertExtractData.setExpertId(String.join(",", extractExpertId));
        projectExpertExtractData.setExpertName(String.join(",", extractExpertName));
        sysProjectExpertExtractService.insertSysProjectExpertExtract(projectExpertExtractData);

        if (residueNum == 1) {
            configData.setExtractStatus(1);
            sysProjectExpertConfigService.updateSysProjectExpertConfig(configData);
        }

        return toAjax(11);
    }
}
